package com.horse.cloud.framework.redis;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

import java.io.Serializable;
import java.util.concurrent.TimeUnit;

/**
 * @create: Created by intelliJIDEA18.1.3
 * @author: bing.Pan
 * @e-mail: 15923508369@163.com
 * @gmdate: 09/08/2018 13:42 星期四
 * @sidesc: redis通用操作API接口，该类不直接提供给业务代码.
 *          子类注入 RedisTemplate 实现扩展
 */
public class RedisCommandAccessor {

    protected final Logger LOGGER = LoggerFactory.getLogger(this.getClass());

    @Autowired  private RedisTemplate<Serializable,Object> redisTemplate;


    private ValueOperations<Serializable, Object> opsForValue() {  return this.redisTemplate.opsForValue(); }


    private ListOperations<Serializable, Object> opsForList(){ return this.redisTemplate.opsForList(); }


    /**
     * 添加数据
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, Object value) {
        boolean result = false;
        try {
            opsForValue().set(key, value);
            result = true;
        } catch (Exception e) {
            LOGGER.error("【framework-redis】redis客户端set值时异常, 异常信息 [{}]",e);
        }
        return result;
    }


    /**
     * 添加数据并设置过去时间
     * @param key
     * @param value
     * @param expireSecondTime
     * @return
     */
    public boolean set(final String key, Object value, Long expireSecondTime) {
        boolean result = false;
        try {
            opsForValue().set(key, value);
            this.redisTemplate.expire(key, expireSecondTime, TimeUnit.SECONDS);
            result = true;
        } catch (Exception e) {
            LOGGER.error("【framework-redis】redis客户端set值时异常, 异常信息 [{}]",e);
        }
        return result;
    }


    /**
     * 添加数据并设置过期时间(自定义过期时间单位类型)
     * @param key
     * @param value
     * @param expireTime
     * @param timeUnit
     * @return
     */
    public boolean set(String key, Object value, Long expireTime, TimeUnit timeUnit) {
        boolean result = false;
        try {
            opsForValue().set(key, value);
            this.redisTemplate.expire(key, expireTime, timeUnit);
            result = true;
        } catch (Exception e) {
            LOGGER.error("【framework-redis】redis客户端set值时异常, 异常信息 [{}]",e);
        }
        return result;
    }


    /**
     * 获取值
     * @param key
     * @return
     */
    public Object get(final String key) {
        return opsForValue().get(key);
    }


    /**
     * 订阅发送
     * @param patternTopic
     * @param value
     */
    public void convertAndSend(String patternTopic, String value){
        this.redisTemplate.convertAndSend(patternTopic,value);
    }


    /**
     * 添加数据，如果存在key则不做任何操作
     * @param key
     * @param value
     * @param expireSecondTime
     * @return
     */
    public boolean setNX(String key, Object value, long expireSecondTime) {
        Boolean ifAbsent = opsForValue().setIfAbsent(key, value);
        if(ifAbsent){
            this.redisTemplate.expire(key, expireSecondTime, TimeUnit.SECONDS);
            return ifAbsent;
        }else{
            return false;
        }
    }


    /**
     * 添加数据，如果存在key则不做任何操作
     * @param key
     * @param value
     * @param expireTime
     * @return
     */
    public boolean setNX(String key, Object value,long expireTime,TimeUnit timeUnit) {
        Boolean ifAbsent = opsForValue().setIfAbsent(key, value);
        if(ifAbsent){
            this.redisTemplate.expire(key, expireTime, timeUnit);
            return ifAbsent;
        }else{
            return false;
        }
    }


    /**
     * list向左侧添加数据
     * @param key
     * @param value
     * @return
     */
    public Object leftPush(String key, Object value){
       return opsForList().leftPush(key,value);

    }

    /**
     * list向左侧添加数据，并设置过期时间
     * @param key
     * @param value
     * @param expireTime
     * @param timeUnit
     * @return
     */
    public Object leftPush(String key, Object value,long expireTime,TimeUnit timeUnit){
        Long aLong = opsForList().leftPush(key, value);
        this.redisTemplate.expire(key, expireTime, timeUnit);
        return aLong;

    }


    /**
     * list向右侧添加数据
     * @param key
     * @param value
     * @return
     */
    public Object rightPuah(String key ,Object value){
        return opsForList().rightPush(key,value);

    }

    /**
     * list向右侧添加数据，并设置过期时间
     * @param key
     * @param value
     * @param expireTime
     * @param timeUnit
     * @return
     */
    public Object rightPuah(String key ,Object value,long expireTime,TimeUnit timeUnit){
        Long aLong = opsForList().rightPush(key, value);
        this.redisTemplate.expire(key,expireTime,timeUnit);
        return aLong;

    }


    public void delete(String key) {
        this.redisTemplate.delete(key);
    }
}
